package com.lhm.video.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.log.Log;

public class ConvertVideo {

	public static String inputPath = PropKit.get("video.input.path");
	public static String outputPath = PropKit.get("video.output.path");
	public static String ffmpegPath = PropKit.get("video.ffmpeg.path");

	public static boolean flag = true;

	private final static Log log = Log.getLog(ConvertVideo.class);

	// 转化视频，转化成果删除文件
	public static boolean process(String filename) {
		boolean status = false;
		// System.out.println("直接转成mp4格式");
		File destFile = new File(outputPath + filename + ".mp4");
		if (destFile.exists() && destFile.isFile()) {
			log.info("同名视频文件已存在，直接删除原文件");
			File file_f = new File(inputPath + filename + ".flv");
			boolean s = file_f.delete();
			if (s) {
				log.info("删除原文件成功:" + inputPath + filename);
			} else {
				log.info("删除原文件失败:" + inputPath + filename);
			}
			status = true;
		} else {
			status = processMp4(filename);// 直接转成mp4格式
			if (status) {
				File file_f = new File(inputPath + filename + ".flv");
				boolean s = file_f.delete();
				if (s) {
					log.info("删除原文件成功:" + inputPath + filename);
				} else {
					log.info("删除原文件失败:" + inputPath + filename);
				}
			}
		}
		return status;
	}

	// 获取待转化的文件，并将其他不需要转化文件送到出口目录去
	public static List<String> listNeedConvertVideoFileNames() {
		List<String> fileNameList = new ArrayList<>();
		File file = new File(inputPath);
		String[] fileNames = file.list();
		if (fileNames != null) {
			for (String fileName : fileNames) {
				if ((StrKit.notBlank(fileName)) && (fileName.endsWith(".flv") || fileName.endsWith(".FLV"))) {
					String filename_true = fileName.substring(0, fileName.lastIndexOf("."));
					fileNameList.add(filename_true);
				} else {
					remove(fileName);
				}
			}
		}
		return fileNameList;
	}

	public static boolean remove(String filename) {
		boolean status = true;
		if (status) {
			status = copyFile(inputPath + filename, outputPath);
			if (status) {
				log.info("文件拷贝成功:" + outputPath + filename);
				File file = new File(inputPath + filename);
				boolean s = file.delete();
				if (s) {
					log.info("删除原文件成功:" + inputPath + filename);
				} else {
					log.info("删除原文件失败:" + inputPath + filename);
				}
			}
		}
		return status;
	}

	private static boolean copyFile(String srcPath, String destDir) {
		boolean flag = false;

		File srcFile = new File(srcPath);
		if (!srcFile.exists()) { // 源文件不存在
			return false;
		}
		// 获取待复制文件的文件名
		File file = new File(srcPath);
		String fileName = file.getName();
		// String fileName = srcPath.substring(srcPath.lastIndexOf("//")+2,
		// srcPath.length());
		// String fileName = srcPath
		// .substring(srcPath.lastIndexOf(File.separator));
		String destPath = destDir + fileName;
		if (destPath.equals(srcPath)) { // 源文件路径和目标文件路径重复
			// System.out.println("源文件路径和目标文件路径重复!");
			return false;
		}
		File destFile = new File(destPath);
		if (destFile.exists() && destFile.isFile()) { // 该路径下已经有一个同名文件
			// System.out.println("目标目录下已有同名文件!");
			log.info("目标目录下已有同名文件,直接删除原文件!" + srcPath);
			boolean s = file.delete();
			if (s) {
				log.info("删除原文件成功:" + srcPath);
			} else {
				log.info("删除原文件失败:" + srcPath);
			}
			return false;
		}

		File destFileDir = new File(destDir);
		destFileDir.mkdirs();
		try {
			FileInputStream fis = new FileInputStream(srcPath);
			FileOutputStream fos = new FileOutputStream(destFile);
			byte[] buf = new byte[1024];
			int c;
			while ((c = fis.read(buf)) != -1) {
				fos.write(buf, 0, c);
			}
			fis.close();
			fos.close();

			flag = true;
		} catch (IOException e) {
			//
		}
		return flag;
	}

	// 对ffmpeg无法解析的文件格式(wmv9，rm，rmvb等), 可以先用别的工具（mencoder）转换为avi(ffmpeg能解析的)格式.
	// private static String processAVI(int type) {
	// List<String> commend = new ArrayList<String>();
	// commend.add(ffmpegPath);
	// commend.add(inputPath);
	// commend.add("-oac");
	// commend.add("lavc");
	// commend.add("-lavcopts");
	// commend.add("acodec=mp3:abitrate=64");
	// commend.add("-ovc");
	// commend.add("xvid");
	// commend.add("-xvidencopts");
	// commend.add("bitrate=600");
	// commend.add("-of");
	// commend.add("mp4");
	// commend.add("-o");
	// commend.add(outputPath + "a.AVI");
	// try {
	// ProcessBuilder builder = new ProcessBuilder();
	// Process process = builder.command(commend).redirectErrorStream(true).start();
	// new PrintStream(process.getInputStream());
	// new PrintStream(process.getErrorStream());
	// process.waitFor();
	// return outputPath + "\\" + "a.AVI";
	// } catch (Exception e) {
	// e.printStackTrace();
	// return null;
	// }
	// }

	// ffmpeg能解析的格式：（asx，asf，mpg，wmv，3gp，mp4，mov，avi，flv等）
	// private static boolean processFlv(String oldfilepath) {
	//
	// List<String> command = new ArrayList<String>();
	// command.add(ffmpegPath);
	// command.add("-i");
	// command.add(oldfilepath);
	// command.add("-ab");
	// command.add("56");
	// command.add("-ar");
	// command.add("22050");
	// command.add("-qscale");
	// command.add("8");
	// command.add("-r");
	// command.add("15");
	// command.add("-s");
	// command.add("600x500");
	// command.add(outputPath + "\\" + "a.flv");
	// try {
	//
	// // 方案1
	// // Process videoProcess = Runtime.getRuntime().exec(ffmpegPath + "ffmpeg -i "
	// +
	// // oldfilepath
	// // + " -ab 56 -ar 22050 -qscale 8 -r 15 -s 600x500 "
	// // + outputPath + "a.flv");
	//
	// // 方案2
	// Process videoProcess = new
	// ProcessBuilder(command).redirectErrorStream(true).start();
	//
	// new PrintStream(videoProcess.getErrorStream()).start();
	//
	// new PrintStream(videoProcess.getInputStream()).start();
	//
	// videoProcess.waitFor();
	//
	// return true;
	// } catch (Exception e) {
	// e.printStackTrace();
	// return false;
	// }
	// }

	private static boolean processMp4(String filename) {

		List<String> command = new ArrayList<String>();
		command.add(ffmpegPath);
		command.add("-i");
		command.add(inputPath + filename + ".flv");
		// 设置高宽比 固定高度360
		command.add("-vf");
		command.add("scale=-2:360");
		command.add("-c:v");
		command.add("libx264");
		// command.add("-crf");
		// command.add("23");
		// command.add("-c:a");
		// command.add("aac");
		// command.add("-strict");
		// command.add("-2");
		// command.add("-f");
		// command.add("mp4");
		command.add(outputPath + filename + ".mp4");
		try {

			// 方案1
			// Process videoProcess = Runtime.getRuntime().exec(ffmpegPath + "ffmpeg -i " +
			// oldfilepath
			// + " -ab 56 -ar 22050 -qscale 8 -r 15 -s 600x500 "
			// + outputPath + "a.flv");

			// 方案2
			Process videoProcess = new ProcessBuilder(command).redirectErrorStream(true).start();

			new PrintStream(videoProcess.getErrorStream()).start();

			new PrintStream(videoProcess.getInputStream()).start();

			videoProcess.waitFor();

			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
}

class PrintStream extends Thread {
	java.io.InputStream __is = null;

	public PrintStream(java.io.InputStream is) {
		__is = is;
	}

	public void run() {
		try {
			while (this != null) {
				int _ch = __is.read();
				if (_ch != -1)
					System.out.print((char) _ch);
				else
					break;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}